package com.yamaikeji.plan.controller;

import com.getui.push.v2.sdk.ApiHelper;
import com.getui.push.v2.sdk.GtApiConfiguration;
import com.getui.push.v2.sdk.api.PushApi;
import com.getui.push.v2.sdk.common.ApiResult;
import com.getui.push.v2.sdk.dto.req.Audience;
import com.getui.push.v2.sdk.dto.req.message.PushChannel;
import com.getui.push.v2.sdk.dto.req.message.PushDTO;
import com.getui.push.v2.sdk.dto.req.message.PushMessage;
import com.getui.push.v2.sdk.dto.req.message.android.GTNotification;
import com.getui.push.v2.sdk.dto.req.message.ios.Alert;
import com.getui.push.v2.sdk.dto.req.message.ios.Aps;
import com.getui.push.v2.sdk.dto.req.message.ios.IosDTO;
import com.yamaikeji.common.annotation.Log;
import com.yamaikeji.common.core.controller.BaseController;
import com.yamaikeji.common.core.domain.AjaxResult;
import com.yamaikeji.common.enums.BusinessType;
import com.yamaikeji.plan.aop.CheckLogin;
import com.yamaikeji.system.domain.plan.Plan;
import com.yamaikeji.system.domain.plan.PlanTask;
import com.yamaikeji.system.domain.plan.Task;
import com.yamaikeji.system.service.plan.IPlanService;
import com.yamaikeji.system.service.plan.IPlanTaskService;
import com.yamaikeji.system.service.plan.ITaskService;
import javapns.devices.Device;
import javapns.devices.implementations.basic.BasicDevice;
import javapns.notification.AppleNotificationServerBasicImpl;
import javapns.notification.PushNotificationManager;
import javapns.notification.PushNotificationPayload;
import javapns.notification.PushedNotification;
import org.apache.commons.collections.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.temporal.TemporalAdjusters;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.stream.Collectors;

/**
 * 任务Controller
 * 
 * @author yamaikeji
 * @date 2023-10-03
 */
@RestController
@RequestMapping("/api/plan/task")
public class TaskController extends BaseController {

    private static final Logger log = LoggerFactory.getLogger(TaskController.class);

    @Autowired
    private ITaskService taskService;

    @Autowired
    private IPlanService planService;

    @Autowired
    private IPlanTaskService planTaskService;

    private static String appId = "7HywUk6MYb7DsEy3QRzo86";
    private static String appKey = "RFoGtKqwLT6ZMiL7iJXtK9";
    private static String masterSecret = "tvIXExymYm7k5P4SPiKnC3";

    /**
     * 查询任务列表
     */
    @CheckLogin
    @PostMapping("/getTaskList")
    public AjaxResult getTaskList(HttpServletRequest req, @RequestBody Task task) {
        long beginTime = System.currentTimeMillis();
        String userNo = (String) req.getAttribute("userNo");
        task.setUserNo(userNo);
        startPage();
        List<Task> list = taskService.selectTaskList(task);
        if (CollectionUtils.isNotEmpty(list)) {
            PlanTask planTask = new PlanTask();
            planTask.setUserNo(userNo);
            planTask.setPlanNoList(list.stream().map(Task::getPlanNo).collect(Collectors.toList()));
            List<PlanTask> planTaskList = planTaskService.selectPlanTaskList(planTask);
            if (CollectionUtils.isNotEmpty(planTaskList)) {
                Map<String, List<PlanTask>> planTaskMap = planTaskList.stream().collect(Collectors.groupingBy(PlanTask::getPlanNo));
                for (Task item : list) {
                    item.setPlanTaskList(planTaskMap.get(item.getPlanNo()));
                }
            }
        }
        long endTime = System.currentTimeMillis();
        log.info("查询任务列表耗时：{}ms", endTime - beginTime);
        return AjaxResult.success(list);
    }

    /**
     * 查询每天任务数
     */
    @CheckLogin
    @PostMapping("/getDayTaskNum")
    public AjaxResult getTaskNumByDay(HttpServletRequest req, @RequestBody Task pTask) {
        List<Task> resTaskList = new ArrayList<>();
        String userNo = (String) req.getAttribute("userNo");
        LocalDate firstDay= LocalDate.now().with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY)).minusDays(7);
        for (int i = 0; i < 21; i++) {
            Task task = new Task();
            task.setId(Long.parseLong(i + ""));
            task.setTaskTime(firstDay.plusDays(i));
            task.setCompleteTaskNum(0);
            task.setNotCompleteTaskNum(0);
            task.setTotalTaskNum(0);
            resTaskList.add(task);
        }
        pTask.setUserNo(userNo);
        pTask.setBeginTime(firstDay);
        pTask.setEndTime(firstDay.plusDays(21));
        List<Task> getTaskList = taskService.selectDayTaskNum(pTask);
        for (Task resTask : resTaskList) {
            for (Task getTaskTime : getTaskList) {
                if (resTask.getTaskTime().equals(getTaskTime.getTaskTime())) {
                    resTask.setCompleteTaskNum(getTaskTime.getCompleteTaskNum());
                    resTask.setNotCompleteTaskNum(getTaskTime.getNotCompleteTaskNum());
                    resTask.setTotalTaskNum(getTaskTime.getTotalTaskNum());
                }
            }
        }
        return AjaxResult.success(resTaskList);
    }

    /**
     * 根据天数查询待办统计
     */
    @CheckLogin
    @PostMapping("/getReportCount")
    public AjaxResult getReportCount(HttpServletRequest req) {
        String userNo = (String) req.getAttribute("userNo");
        Task getTask = new Task();
        getTask.setUserNo(userNo);
        getTask = taskService.selectReportCount(getTask);
        int taskCompleteRate;
        if (getTask.getTotalTaskNum() == 0) {
            taskCompleteRate = 0;
        } else {
            taskCompleteRate = (int)(Float.valueOf(getTask.getCompleteTaskNum()) / Float.valueOf(getTask.getTotalTaskNum()) * 100);
        }
        getTask.setTaskCompleteRate(taskCompleteRate);
        return AjaxResult.success(getTask);
    }

    /**
     * 根据天数查询待办统计
     */
    @CheckLogin
    @PostMapping("/getReportChart")
    public AjaxResult getReportChart(HttpServletRequest req, @RequestBody Task pTask) {
        List<Task> resTaskList = new ArrayList<>();
        String userNo = (String) req.getAttribute("userNo");
        pTask.setUserNo(userNo);
        List<Task> getTaskList = taskService.selectReportChart(pTask);
        for (int i = 7; i > 0; i--) {
            Task task = new Task();
            task.setId(Long.parseLong(i + ""));
            task.setTaskTime(LocalDate.now().minusDays(i));
            task.setCompleteTaskNum(0);
            task.setNotCompleteTaskNum(0);
            task.setTotalTaskNum(0);
            resTaskList.add(task);
        }
        for (Task resTask : resTaskList) {
            for (Task getTaskTime : getTaskList) {
                if (resTask.getTaskTime().equals(getTaskTime.getTaskTime())) {
                    resTask.setCompleteTaskNum(getTaskTime.getCompleteTaskNum());
                    resTask.setNotCompleteTaskNum(getTaskTime.getNotCompleteTaskNum());
                    resTask.setTotalTaskNum(getTaskTime.getCompleteTaskNum() + getTaskTime.getNotCompleteTaskNum());
                }
            }
        }
        return AjaxResult.success(resTaskList);
    }

    /**
     * 根据天数分页查询待办
     */
    @CheckLogin
    @PostMapping("/getReportTaskList")
    public AjaxResult getReportTaskList(HttpServletRequest req, @RequestBody Task task) {
        String userNo = (String) req.getAttribute("userNo");
        task.setUserNo(userNo);
        startPage();
        List<Task> taskList = taskService.selectReportTaskList(task);
        return AjaxResult.success(taskList);
    }

    /**
     * 查询任务完成进度
     */
    @CheckLogin
    @PostMapping("/getTaskCompleteRate")
    public AjaxResult getTaskCompleteRate(HttpServletRequest req) {
        String userNo = (String) req.getAttribute("userNo");
        Task getTask = new Task();
        getTask.setUserNo(userNo);
        List<Task> totalTaskList = taskService.selectTaskList(getTask);
        getTask.setTaskStatus("1");
        List<Task> completeTaskList = taskService.selectTaskList(getTask);
        Task task = new Task();
        task.setTotalTaskNum(totalTaskList.size());
        task.setCompleteTaskNum(completeTaskList.size());
        Float taskCompleteRate;
        if (totalTaskList.size() == 0) {
            taskCompleteRate = 0f;
        } else {
            taskCompleteRate = Float.valueOf(completeTaskList.size()) / Float.valueOf(totalTaskList.size());
        }
        return AjaxResult.success(taskCompleteRate);
    }

    /**
     * 修改任务
     */
    @CheckLogin
    @Log(title = "修改任务", businessType = BusinessType.UPDATE)
    @PostMapping("/editTask")
    public AjaxResult editTask(HttpServletRequest req, @RequestBody Task task) {
        String userNo = (String) req.getAttribute("userNo");
        Plan getPlan = new Plan();
        getPlan.setUserNo(userNo);
        getPlan.setPlanNo(task.getPlanNo());
        getPlan = planService.selectPlan(getPlan);
        if ("1".equals(getPlan.getPlanTimeType())) {
            if ("0".equals(task.getTaskStatus())) {
                Plan updatePlan = new Plan();
                updatePlan.setPlanNo(task.getPlanNo());
                updatePlan.setPlanStatus("2");
                planService.updatePlan(updatePlan);
            } else if ("1".equals(task.getTaskStatus())) {
                Plan updatePlan = new Plan();
                updatePlan.setPlanNo(task.getPlanNo());
                updatePlan.setPlanStatus("3");
                planService.updatePlan(updatePlan);
            }
        }
        return AjaxResult.success(taskService.updateTask(task));
    }

    /**
     * 更新使用时间
     */
    @CheckLogin
    @Log(title = "更新使用时间", businessType = BusinessType.UPDATE)
    @PostMapping("/editUseTime")
    public AjaxResult editUseTime(HttpServletRequest req, @RequestBody Task task) {
        String userNo = (String) req.getAttribute("userNo");
        task.setUserNo(userNo);
        taskService.updateUseTime(task);
        Plan plan = new Plan();
        plan.setUserNo(userNo);
        plan.setPlanNo(task.getPlanNo());
        plan.setUseTime(task.getUseTime());
        planService.updateUseTime(plan);
        return AjaxResult.success(1);
    }

    /**
     * 删除任务
     */
    @CheckLogin
    @Log(title = "删除任务", businessType = BusinessType.UPDATE)
    @PostMapping("/deleteTask")
    public AjaxResult deleteTask(@RequestBody Task task) {
        return AjaxResult.success(taskService.updateTask(task));
    }

    /**
     * 个推推送任务
     */
    @Log(title = "推送任务", businessType = BusinessType.UPDATE)
    @PostMapping("/geTuiPushTask")
    public AjaxResult geTuiPushTask(@RequestBody Task task) {
        try {
            GtApiConfiguration apiConfiguration = new GtApiConfiguration();
            //填写应用配置
            apiConfiguration.setAppId(appId);
            apiConfiguration.setAppKey(appKey);
            apiConfiguration.setMasterSecret(masterSecret);
            // 接口调用前缀，请查看文档: 接口调用规范 -> 接口前缀, 可不填写appId
            apiConfiguration.setDomain("https://restapi.getui.com/v2/");
            // 实例化ApiHelper对象，用于创建接口对象
            ApiHelper apiHelper = ApiHelper.build(apiConfiguration);
            // 创建对象，建议复用。目前有PushApi、StatisticApi、UserApi
            PushApi pushApi = apiHelper.creatApi(PushApi.class);

            //根据cid进行单推
            PushDTO<Audience> pushDTO = new PushDTO<Audience>();
            // 设置推送参数
            pushDTO.setRequestId(System.currentTimeMillis() + "");
            /**** 设置个推通道参数 *****/
            PushMessage pushMessage = new PushMessage();
            pushDTO.setPushMessage(pushMessage);
            GTNotification notification = new GTNotification();
            pushMessage.setNotification(notification);
            notification.setTitle("个title");
            notification.setBody("个body");
            notification.setClickType("url");
            notification.setUrl("https://www.getui.com");
            /**** 设置个推通道参数，更多参数请查看文档或对象源码 *****/

            /**** 设置厂商相关参数 ****/
            PushChannel pushChannel = new PushChannel();
            pushDTO.setPushChannel(pushChannel);

            /*设置ios厂商参数*/
            IosDTO iosDTO = new IosDTO();
            pushChannel.setIos(iosDTO);
            //相同的collapseId会覆盖之前的消息
            iosDTO.setApnsCollapseId(UUID.randomUUID().toString());
            Aps aps = new Aps();
            iosDTO.setAps(aps);
            Alert alert = new Alert();
            aps.setAlert(alert);
            alert.setTitle("ios title");
            alert.setBody("ios body");
            /*设置ios厂商参数结束，更多参数请查看文档或对象源码*/

            /*设置接收人信息*/
            Audience audience = new Audience();
            pushDTO.setAudience(audience);
            audience.addCid("5313a86cb2f84dae1d765a9fd4ee08e9");
            /*设置接收人信息结束*/
            /**** 设置厂商相关参数，更多参数请查看文档或对象源码 ****/

            // 进行cid单推
            ApiResult<Map<String, Map<String, String>>> apiResult = pushApi.pushToSingleByCid(pushDTO);
            if (apiResult.isSuccess()) {
                // success
                System.out.println(apiResult.getData());
            } else {
                // failed
                System.out.println("code:" + apiResult.getCode() + ", msg: " + apiResult.getMsg());
            }
        } catch (Exception e) {
            logger.error(e.getMessage());
        }
        return AjaxResult.success(taskService.updateTask(task));
    }

    /**
     * 推送任务
     */
    @Log(title = "推送任务", businessType = BusinessType.UPDATE)
    @PostMapping("/pushTask")
    public AjaxResult pushTask(@RequestBody Task task) {
        try {
            System.out.println("zsl==========开始推送消息");
            int badge = 1; // 图标小红圈的数值
            String sound = "default"; // 铃音
            // 要推送的，手机设备token号
            String deviceToken = "ce1f8157c3b726ecf1f2eecb9ac966150cc2daf2fee37b381c4e8f4620c51b36";
            // 这里是要推送的测试消息
            String message = "test push message to ios device";

            List<String> tokens = new ArrayList<String>();
            tokens.add(deviceToken);

            // java必须要用导出p12文件 ,php的话是pem文件
            // 注意证书是生产环境还是测试环境
            String certificatePath = "cms-plan/src/main/resources/aps_plan.p12";
            // 从mac钥匙串，导出证书时设置的密码
            String msgCertificatePassword = "yamaios";

            boolean sendCount = true;

            PushNotificationPayload payload = new PushNotificationPayload();
            payload.addAlert(message); // 消息内容
            //payload.addBadge(badge);
            //payload.addCustomDictionary("uid", "haahi");
            //payload.addCustomDictionary("type", 12);
            //payload.addCustomDictionary("title", "haahi");
            payload.addSound(sound);// 铃音

            PushNotificationManager pushManager = new PushNotificationManager();
            // true：对应iOS生产环境推送 false：对应iOS测试环境推送
            pushManager.initializeConnection(new AppleNotificationServerBasicImpl(certificatePath, msgCertificatePassword, false));
            List<PushedNotification> notifications = new ArrayList<PushedNotification>();
            // 开始推送消息
            if (sendCount) {
                Device device = new BasicDevice();
                device.setToken(deviceToken);
                PushedNotification notification = pushManager.sendNotification(device, payload, false);
                notifications.add(notification);
            } else {
                List<Device> devices = new ArrayList<Device>();
                for (String token : tokens) {
                    devices.add(new BasicDevice(token));
                }
                notifications = pushManager.sendNotifications(payload, devices);
            }

            List<PushedNotification> failedNotification = PushedNotification.findFailedNotifications(notifications);
            List<PushedNotification> successfulNotification = PushedNotification
                    .findSuccessfulNotifications(notifications);
            int failed = failedNotification.size();
            int successful = successfulNotification.size();
            System.out.println("zsl==========成功数：" + successful);
            System.out.println("zsl==========失败数：" + failed);
            pushManager.stopConnection();
            System.out.println("zsl==========消息推送完毕");
        } catch (Exception e) {
            e.printStackTrace();
        }
        return AjaxResult.success(taskService.updateTask(task));
    }
}
